package info.motteke.mixivoice4j.http.html;

import info.motteke.mixivoice4j.Body;
import info.motteke.mixivoice4j.ImageUrl;
import info.motteke.mixivoice4j.MixiVoiceException;
import info.motteke.mixivoice4j.http.StringImageUrl;
import info.motteke.util.StringUtil;

import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

public class RecentVoiceEntry {

    private static final Log log = LogFactory.getLog(RecentVoiceEntry.class);

    private final Element archive;

    private final Element img;

    private final String[] imageData;

    public RecentVoiceEntry(Element archive) {
        this.archive = archive;
        this.img = getImage(archive);
        this.imageData = getImageData();
    }

    private boolean hasImage() {
        return img != null;
    }

    private Element getImage(Element archive) {
        Elements img = archive.select("span.voicePhoto > img");

        if (img.size() == 0) {
            return null;
        } else {
            return img.first();
        }
    }

    private String[] getImageData() {
        String[] ret;

        if (img == null) {
            ret = null;
        } else {
            ret = img.attr("id").split(":");
            String id = ret[0];
            ret[0] = id.substring("photo_".length(), id.length());
        }

        return ret;
    }

    public String getImageId() {
        return imageData[0];
    }

    public String getImagePostKey() {
        return imageData[2];
    }

    public List<RecentVoiceComment> getComments() {
        List<RecentVoiceComment> ret = new ArrayList<RecentVoiceComment>();

        for (Element el : getCommentElements()) {
            ret.add(new RecentVoiceComment(el));
        }

        return ret;
    }

    private Elements getCommentElements() {
        return archive.select(".voiceArea dl.comment > dd");
    }

    public long getId() {
        Elements postTime = archive.select(".postTime");

        if (postTime.size() == 0) {
            throw new MixiVoiceException("最新のつぶやきにある投稿の投稿時刻が取得できません。");
        }
        return Long.parseLong(postTime.get(0).val());
    }

    public RecentVoiceEntryUser getUser() {
        return new RecentVoiceEntryUser(archive);
    }

    public Body getBody() {
        Elements bodies = archive.select(".voiced > p");

        if (bodies.size() == 0) {
            throw new MixiVoiceException("最新のつぶやきのエントリから本文を取得できません。");

        }
        return new Body(bodies.get(0));
    }

    public ImageUrl getImageThumbnailUrl() {
        if (!hasImage()) {
            return null;
        } else {
            return new StringImageUrl(img.attr("src"));
        }
    }

    public Set<RecentVoiceFavoriteUser> getFavorites() {
        Set<RecentVoiceFavoriteUser> set = new LinkedHashSet<RecentVoiceFavoriteUser>();

        for (Element fav : archive.select(".voiceArea dl.listIine > dd.feedback")) {
            set.add(new RecentVoiceFavoriteUser(fav));
        }

        return set;
    }

    public int getCommentCount() {
        Elements count = archive.select("p.moreLink01 > a > span.commentCount");
        if (count.size() == 0) {
            return 0;
        } else {
            return Integer.parseInt(count.text());
        }
    }

    public int getFavoritesCount() {
        Elements favCount = archive.select(".voiceArea dl.listIine > dt span.feedbackTotalCount");

        String key = getUser().getNickName() + ":" + getId();
        if (favCount.size() == 0) {
            log.info(key + "にはイイネ！が付いていません。");
        } else {
            log.info(key + "にはイイネ！が付いています。");
        }

        return StringUtil.parseInt(favCount.text(), 0);
    }
}
